<template>
  <Draggable
    :list="modelItems"
    :group="{ name: 'sharted', pull: true, put: true }"
    :ghost-class="'pvtPlaceholder'"
    :prevent-on-filter="false"
    :class="classes"
    @change="onDragEnd"
    :move="onDragMove"
  >
    <VDraggableAttribute
      v-for="item in modelItems"
      :key="item"
      :restricted="restrictedFromDragDrop.includes(item)"
      :open="openStatus[item]"
      :unselected-filter-values="valueFilter[item]"
      :attributeName="item"
      :attribute-values="allFilters[item]"
      :z-index="zIndices[item] || maxZIndex"
      :hide-drop-down-for-unused="hideDropDownForUnused"
      @update:z-index-of-filter-box="$emit('update:zIndexOfFilterBox', $event)"
      @update:unselected-filter-values="
        $emit('update:unselectedFilterValues', $event)
      "
      @update:open-status-of-filter-box="
        $emit('update:openStatusOfFilterBox', $event)
      "
    >
      <template #pvtAttr="{ attrName }">
        <slot
          name="pvtAttr"
          :attr-name="attrName"
        >
          {{ getCaption(attrName) }}
        </slot>
      </template>
    </VDraggableAttribute>
  </Draggable>
</template>

<script setup>
import { ref, onMounted, computed, watch } from 'vue'
import { VueDraggableNext as Draggable } from 'vue-draggable-next'
import VDraggableAttribute from './VDraggableAttribute.vue'

const emit = defineEmits([
  'update:draggedAttribute',
  'update:zIndexOfFilterBox',
  'update:unselectedFilterValues',
  'update:openStatusOfFilterBox'
])

const props = defineProps({
  cellType: {
    type: String,
    required: true
  },
  classes: {
    type: String,
    default: ''
  },
  attributeNames: {
    type: Array,
    default: () => []
  },
  allFilters: {
    type: Object,
    default: () => ({})
  },
  valueFilter: {
    type: Object,
    default: () => ({})
  },
  restrictedFromDragDrop: {
    type: Array,
    default: () => []
  },
  hideFilterBoxOfUnusedAttributes: {
    type: Boolean,
    default: false
  },
  zIndices: {
    type: Object,
    default: () => ({})
  },
  maxZIndex: {
    type: Number,
    default: 1000
  },
  openStatus: {
    type: Object,
    default: () => ({})
  },
  multiple: {
    type: Boolean,
    default: false
  },
  fields: {
    type: Array,
    default: () => []
  }
})

const modelItems = ref([])

const onDragMove = (event) => {
  const draggedItem = event.draggedContext.element
  const isCrossCellMove = event.from !== event.to

  if (isCrossCellMove && props.restrictedFromDragDrop.includes(draggedItem)) {
    return false
  }

  return true
}

const onDragEnd = () => {
  if (props.cellType !== 'unused') {
    if (props.cellType === 'cols' && props.multiple) {
      emit('update:draggedAttribute', {
        key: props.cellType,
        value: [...modelItems.value, 'srfname']
      })
    } else {
      emit('update:draggedAttribute', {
        key: props.cellType,
        value: modelItems.value
      })
    }
  }
}

onMounted(() => {
  modelItems.value = [...props.attributeNames]
})

watch(() => props.attributeNames, () => {
   modelItems.value = [...props.attributeNames]
})

const hideDropDownForUnused = computed(() => {
  return props.cellType === 'unused' && props.hideFilterBoxOfUnusedAttributes
})

const getCaption = (codeName) => {
  const item = props.fields.find(x => x.codeName === codeName);
  if (item) {
    return item.caption;
  }
  return codeName;
}
</script>

<style scoped></style>
